﻿using System;
using System.Reflection;
using System.Reflection.Emit;

namespace TypeBuilderFx.Core
{
    /// <summary>Extends a <see cref="ModuleBuilder"/> with higher-level methods.</summary>
    public class ModuleBuilderExtender
    {
        private readonly ModuleBuilder _moduleBuilder;

        /// <summary>Construct an extender by wrapping a <see cref="ModuleBuilder"/>.</summary>
        /// <param name="moduleBuilder"></param>
        public ModuleBuilderExtender(ModuleBuilder moduleBuilder)
        {
            _moduleBuilder = moduleBuilder;
        }

        /// <summary>Exposes the underlying <see cref="ModuleBuilder"/>.</summary>
        public ModuleBuilder ModuleBuilder
        {
            get { return _moduleBuilder; }
        }

        /// <summary>Creates a public type.</summary>
        /// <param name="typeFullName"></param>
        /// <param name="baseType"></param>
        /// <param name="interfacesToImplement"></param>
        /// <returns></returns>
        public TypeBuilderExtender CreateType(string typeFullName, Type baseType, params Type[] interfacesToImplement)
        {
            TypeBuilder typeBuilder = ModuleBuilder.DefineType(
                typeFullName,
                TypeAttributes.Public
                | TypeAttributes.Class
                | TypeAttributes.AutoClass
                | TypeAttributes.AnsiClass
                | TypeAttributes.AutoLayout,
                baseType,
                interfacesToImplement);

            return new TypeBuilderExtender(typeBuilder);
        }
    }
}